package cn.yitun.chat.yitunservermanagecore.general.manage.system.service.impl;

import cn.yitun.chat.yituncommonmessage.ExceptionEnum;
import cn.yitun.chat.yituncommonmessage.YitunException;
import cn.yitun.chat.yituncommonutil.YitunMapUtil;
import cn.yitun.chat.yituncommonutil.YitunObjectUtil;
import cn.yitun.chat.yitunservercommonlib.basebean.web.JwtUserDto;
import cn.yitun.chat.yitunservercommonlib.constant.Constants;
import cn.yitun.chat.yitunservercommonlib.converter.ot.TreeMenuConverter;
import cn.yitun.chat.yitunservercommonlib.crud.yitun.CrudServiceImpl;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.common.Tree;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.system.MenuDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.MenuInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.user.UserInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.MenuTreeTableVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.MenuVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.RouterVo;
import cn.yitun.chat.yitunservercommonlib.enums.system.MenuTypeEnums;
import cn.yitun.chat.yitunservercommonlib.util.BuildTree;
import cn.yitun.chat.yitunserverimbase.dao.system.MenuDao;
import cn.yitun.chat.yitunserverimbase.dao.system.RoleMenuDao;
import cn.yitun.chat.yitunserverimbase.dao.system.UserDao;
import cn.yitun.chat.yitunservermanagecore.general.manage.system.service.MenuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * date 2018-06-04 17:20:12<br>
 * description
 * 
 * @author yitun<br>
 * @since
 */
@Service
public class MenuServiceImpl
		extends CrudServiceImpl<MenuDao,MenuDto, MenuInfo, MenuVo>
		implements MenuService {

	@Resource
	private UserDao userDao;

	@Resource
	private RoleMenuDao  roleMenuDao;

	@Override
	public List<MenuInfo> queryList(MenuDto menu) {
		return dao.list(menu == null ? null : YitunMapUtil.java2Map(menu, false));
	}
	@Override
	public List<MenuVo> listVo(MenuDto menu) {
		return dao.listVO(menu == null ? null : YitunMapUtil.java2Map(menu, false));
	}


	/**
	 * 修改菜单图标
	 * date 2018-07-12 11:11:35<br>
	 * description
	 * @author yitun<br>
	 * @param id
	 * @param icon
	 * @return
	 * @since
	 */
	@Override
	@Transactional
	public int updateIcon(Long id, String icon) {
		return dao.updateIcon(id, icon);
	}
	/**
	 * 更新菜单状态
	 * @param id
	 * @param status
	 */
	@Override
	@Transactional
	public int updateVisible(Long id, Boolean status) {
		return dao.updateVisible(id, status);
	}

	/**
	 * date 2018-07-12 11:29:19<br>
	 * description 条件获取菜单
	 * @author yitun<br>
	 * @param menuQuery
	 * @return
	 * @since
	 */
	@Override
	public List<MenuInfo> list(MenuDto menuQuery) {
		List<MenuInfo> list = dao.list(YitunMapUtil.java2Map(menuQuery, false));
		return list;
	}

	/**
	 * 获取角色下的权限所有id
	 *
	 * @param roleId
	 * @return
	 */
	@Override
	public List<Long> menuIdsByRoleId(Long roleId) {
		// 根据roleId查询权限,只保留子节点，父节点的选中或半选中状态，前台自动调整
		List<MenuVo> menus = listVO(new HashMap<String, Object>(16));
		List<Long> menuIds = roleMenuDao.listMenuIdByRoleId(roleId);
		List<Long> temp = menuIds;
		for (MenuVo menu : menus) {
			if (temp.contains(menu.getParentId())) {
				menuIds.remove(menu.getParentId());
			}
		}
		return menuIds;
	}

	/**
	 * 获取角色菜单
	 * @param roleId
	 * @return
	 */
	@Override
	public List<MenuVo> getRoleMenuListByRoleId(Long roleId) {
		List<MenuVo> roleMenuList = dao.roleMenuLis(roleId);
		return roleMenuList;
	}
	/**
	 * 获取用户权限
	 * @param userId
	 * @return
	 */
	@Override
	public List<MenuVo> getUserMenuListByCurrentUserId(Long userId) {
		return null;
	}

	/**
	 * 获取角色树
	 * @param jwtUserDto
	 * @return
	 */
	@Override
	public Tree<MenuVo> getTree(JwtUserDto jwtUserDto) {
		List<Tree<MenuVo>> trees = new ArrayList<>();
		Map<String , Object> params = new HashMap<>();
		List<MenuVo> menuDOs = dao.listVO(params);
		List<Long> rootMenus = new ArrayList<>();
		UserInfo currentUser = userDao.get(jwtUserDto.getUserId());
		for (MenuVo sysMenuDO : menuDOs) {
			Tree<MenuVo> tree = new Tree<>();

			tree.setParentName(sysMenuDO.getParentName());
			if (sysMenuDO.getParentId() == null || sysMenuDO.getParentId() == 0 ){
				sysMenuDO.setParentName("项级节点");
				tree.setParentName("项级节点");
			}
			tree.setId(sysMenuDO.getId().toString());
			tree.setParentId(sysMenuDO.getParentId().toString());
			tree.setText(sysMenuDO.getName());
			trees.add(tree);
		}
		// 默认顶级菜单为０，根据数据库实际情况调整
		Tree<MenuVo> t = BuildTree.build(trees);
		return t;
	}
	/**
	 * 角色表格树
	 * @param userDTO
	 * @return
	 */
	@Override
	public List<MenuTreeTableVo> treeTable(JwtUserDto userDTO) {
		Map<String , Object> params = new HashMap<>();
		List<MenuVo> menuDOs = dao.listVO(params);
		List<MenuTreeTableVo> RouterInfos = new ArrayList<>();
		MenuTreeTableVo vo = null;
		for (MenuVo menu : menuDOs) {
			vo = TreeMenuConverter.INSTANCE.vo2treevo(menu);
			RouterInfos.add(vo);
		}
		return MenuTreeTableVo.buildList(RouterInfos, 0l);
	}

	/**
	 * 用户的路由
	 * @return
	 */
	@Override
	public List<RouterVo> routerInfosByUserId(JwtUserDto userDTO) {
		List<MenuVo> Menus =dao.listMenuByUserIdAndCompanyId(userDTO.getUserId());
		List<RouterVo> RouterInfos = new ArrayList<>();
		for (MenuVo menu : Menus) {
			RouterVo routerInfo = new RouterVo();
			routerInfo.setId(menu.getId().toString());
			routerInfo.setParentId(menu.getParentId().toString());
			routerInfo.setPath(menu.getUrl());
			routerInfo.setComponent(menu.getComponent());
			routerInfo.setName(menu.getName());
			routerInfo.setIconCls(menu.getIcon());
			routerInfo.setHidden( "0".equals(menu.getVisible()) );
			routerInfo.setChildren(new ArrayList<>());
			routerInfo.setLeaf(null!=menu.getType()&& (menu.getType().equals(MenuTypeEnums.TYPE_FUNCTION.getType())));
			RouterInfos.add(routerInfo);
		}
		return RouterVo.buildList(RouterInfos, "0");
	}

	/**
	 * 校验菜单名称是否唯一
	 * @param menu 菜单信息
	 * @return 结果
	 */
	@Override
	public Boolean checkMenuNameUnique(MenuInfo menu) {
		Long menuId = YitunObjectUtil.isEmpty(menu.getId()) ? -1 : menu.getId();
		Long parentId = YitunObjectUtil.isEmpty(menu.getParentId()) ? 0 : menu.getParentId();

		MenuInfo info = dao.checkMenuNameUnique(menu.getName(), parentId);
		if (YitunObjectUtil.isNotEmpty(info) && info.getId() != menuId ) {
			return Constants.MENU_NAME_NOT_UNIQUE;
		}
		return !Constants.MENU_NAME_NOT_UNIQUE;
	}

	/**
	 * 用户权限
	 * @param userId
	 * @return
	 */
	@Override
	public List<String> selPermList(Long userId) {
		return dao.listUserPerms(userId);
	}

	@Transactional
	@Override
	public void removeMenu(Long menuId) {
		MenuInfo menu = get(menuId);
		if (menu == null || menu.getType() == null)
			throw new YitunException(ExceptionEnum.LOSE_FILED);
		if ( !MenuTypeEnums.TYPE_LIST.getType().equals(menu.getType())
				&& !MenuTypeEnums.TYPE_MENU.getType().equals(menu.getType())
				&& !MenuTypeEnums.TYPE_FUNCTION.getType().equals(menu.getType()))
			throw new YitunException(ExceptionEnum.LOSE_FILED);
		if (dao.count(mapModel("parentId" , menuId) ) > 0 ){
			throw new YitunException(ExceptionEnum.MENU_HAS_SON);
		}
		if (remove(menuId) == 0) {
			throw new YitunException(ExceptionEnum.DO_FAIL);
		}
//        redisManager.del(CommonConstant.MENU_ROLE_PERMS_KEY);
//            dao.batchremoveByParentId(menuId);
	}
}
